/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jili.ubert.clientapi;

import com.jili.ubert.clientapi.until.UnWorkException;
import com.jili.ubert.clientapi.until.AnswerHandler;
import com.jili.ubert.clientapi.provider.HistoryDataProvider;
import com.jili.ubert.clientapi.provider.ManagementProvider;
import com.jili.ubert.clientapi.provider.MarketDataProvider;
import com.jili.ubert.clientapi.provider.TradeProvider;
import com.jili.ubert.code.ReturnIDEntity;
import com.jili.ubert.code.client2server.Login;
import com.jili.ubert.code.server2client.MsgResult;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author ChengJili
 */
public class ClientAPI {

    private static final Log log = LogFactory.getLog(ClientAPI.class);
    //1.变量对象
    private final TradeProvider tradeProvider;
    private final MarketDataProvider marketDataProvider;
    private final ManagementProvider managementProvider;
    private final HistoryDataProvider historyDataProvider;

    private final TradeClient tradeClient;
    private final MarketDataClient marketDataClient;
    private final HistoryDataClient historyDataClient;
    private final ExecutorService exec = Executors.newFixedThreadPool(3);
    
    private final TradeRequest tradeRequest;
    private final HistoryDataRequest historyDataRequest;
    private final MarketDataRequest marketDataRequest;
    private final DataPool dataPool;
    
    private Login login;

    private boolean isConnectTrade = false;
    private boolean isConnectMarketData = false;
    private boolean isConnectHistoryData = false;

    private boolean isLoginTrade = false;
    private boolean isLoginMarketData = false;
    private boolean isLoginHistoryData = false;
    //工作线程池
    private static ThreadPoolExecutor workExecutor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
    
    public static void WorkRun(Runnable command){
        workExecutor.execute(command);
    }
    public void Close(){
        //1.关闭线程池
        
        //2.netty链接退出
        
        //3.
    }

    //2.构造函数
    private void version() {
        System.out.println("API版本1.0.0");
        log.info("API版本1.0.0");
    }

    public ClientAPI() {
        this.tradeClient = new TradeClient();
        this.marketDataClient = new MarketDataClient();
        this.historyDataClient = new HistoryDataClient();
        tradeRequest = new TradeRequest(); 
        historyDataRequest = new HistoryDataRequest(); 
        marketDataRequest = new MarketDataRequest(); 
        dataPool = new DataPool(); 
        
        tradeClient.setDataPool(dataPool);
        tradeClient.setRequest(tradeRequest);
        marketDataClient.setDataPool(dataPool);
        marketDataClient.setRequest(marketDataRequest);
        historyDataClient.setDataPool(dataPool);
        historyDataClient.setRequest(historyDataRequest);
        tradeRequest.setDataPool(dataPool);
        historyDataRequest.setDataPool(dataPool);
        marketDataRequest.setDataPool(dataPool);
        

        this.tradeProvider = (TradeProvider) this.tradeClient;
        this.managementProvider = (ManagementProvider) this.tradeClient;
        this.marketDataProvider = (MarketDataProvider) this.marketDataClient;
        this.historyDataProvider = (HistoryDataProvider) this.historyDataClient;
        log.debug("ClientAPI构造完成");
        version();
    }

    public ClientAPI(String tradeHost, int tradePort, String marketDataHost, int marketDataPort, String historyDataHost, int historyDataPort) {
        this.tradeClient = new TradeClient(exec, tradeHost, tradePort);
        this.marketDataClient = new MarketDataClient(marketDataHost, marketDataPort);
        this.historyDataClient = new HistoryDataClient(historyDataHost, historyDataPort);

        this.tradeProvider = (TradeProvider) tradeClient;
        this.managementProvider = (ManagementProvider) tradeClient;
        this.marketDataProvider = (MarketDataProvider) marketDataClient;
        this.historyDataProvider = (HistoryDataProvider) historyDataClient;
        version();
    }

    //3.connect方法
    public MsgResult ConnectTradeServer(String host, int port) {
        System.out.println("API执行登陆");
        return ConnectTradeServer(host, port, false, false);
    }

    public MsgResult ConnectTradeServer(String host, int port, boolean isSSL, boolean isZlib) {
        log.debug("正在登陆IP:" + host + "  Port:" + port);
        MsgResult ret = tradeClient.Connect(exec, host, port, isSSL, isZlib);
        if (ret.getSuccess()) {
            isConnectTrade = true;

        }
        return ret;
    }

    public MsgResult ConnectMarketDataServer(String host, int port) {
        try {
            return ConnectMarketDataServer(host, port, false, false);
        } catch (IOException ex) {
            Logger.getLogger(ClientAPI.class.getName()).log(Level.SEVERE, null, ex);
            return ReturnIDEntity.failConnect;
        }
    }

    public MsgResult ConnectMarketDataServer(String host, int port, boolean isSSL, boolean isZlib) throws IOException {
        //    return marketDataClient.Connect(host,port,isSSL,isZlib);
        MsgResult ret = marketDataClient.Connect(host, port, isSSL, isZlib);
        if (ret.getSuccess()) {
            isConnectMarketData = true;
            if (login != null) {
                LoginMarketDataServer(login,new AnswerHandler<MsgResult>(){

                    @Override
                    public void OnAnswer(MsgResult anwer) {
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                    }

                    @Override
                    public void IsSuccess() {
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                    }

                    @Override
                    public void IsFalse(MsgResult rst) {
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                    }
                });
            }
        }
        return ret;
    }

    public MsgResult ConnectHistoryDataServer(String host, int port) {
        try {
            return ConnectHistoryDataServer(host, port, false, false);
        } catch (IOException ex) {
            Logger.getLogger(ClientAPI.class.getName()).log(Level.SEVERE, null, ex);
            return ReturnIDEntity.failConnect;
        }
    }

    public MsgResult ConnectHistoryDataServer(String host, int port, boolean isSSL, boolean isZlib) throws IOException {
        //    return historyDataClient.Connect(host,port,isSSL,isZlib);
        MsgResult ret = historyDataClient.Connect(host, port, isSSL, isZlib);
        if (ret.getSuccess()) {
            isConnectHistoryData = true;
            if (login != null) {
                LoginHistoryDataServer(login,new AnswerHandler<MsgResult>(){

                    @Override
                    public void OnAnswer(MsgResult anwer) {
                    }

                    @Override
                    public void IsSuccess() {
                    }

                    @Override
                    public void IsFalse(MsgResult rst) {
                    }
            });
            }
        }
        return ret;
    }

    public int LoginTradeServer(Login login, AnswerHandler<MsgResult> handler) throws IOException {
        if (isConnectTrade) {
            return tradeClient.Login(login, handler);
        } else {
            throw new UnWorkException("还没有连接交易后台，请连接后登陆");
        }
    }

    public int LoginMarketDataServer(Login login,AnswerHandler<MsgResult> handler) throws IOException {
        this.login = login;
        MsgResult ret;
        if (isConnectMarketData) {
            return marketDataClient.Login(login, handler);
        } else {
            throw new UnWorkException("还没有连接交易后台，请连接后登陆");
        }
    }

    public int LoginHistoryDataServer(Login login,AnswerHandler<MsgResult> handler) throws IOException {
        this.login = login;
        int ret=0;
        if (isConnectHistoryData) {
            ret = historyDataClient.UserLogin(login,handler);
        } else {
            handler.IsFalse(ReturnIDEntity.failLogin);
        }
        return ret;
    }

    public int[] LoginServer(Login login, AnswerHandler<MsgResult> handler) throws IOException {
        int[] a = new int[3];
        if (isConnectTrade) {
            a[0] = tradeClient.UserLogin(login, handler);
        } else {
            throw new UnWorkException("还没有连接交易后台，请连接后登陆");
        }
        return a;
    }

    public int UserLogin(String userName, String passWord,AnswerHandler<MsgResult> handler) throws IOException {
        Login login0 = new Login(userName, passWord);
        if (isConnectTrade) {
            return tradeClient.UserLogin(login0, handler);
        } else {
            throw new UnWorkException("还没有连接交易后台，请连接后登陆");
        }

    }

    public int getVerlidCode(AnswerHandler<String> handler) {
        return tradeClient.getVerlidCode(handler);
    }
    //4.getProvider方法

    /**
     * @return the tradeProvider
     */
    public TradeProvider getTradeProvider() {
        if (isLoginTrade) {
            return tradeProvider;
        } else {
            return tradeProvider;
        //    throw new UnWorkException("还没有登录，请先登录后使用");
        }
    }

    /**
     * @return the marketDataProvider
     */
    public MarketDataProvider getMarketDataProvider() {
        if (isLoginMarketData) {
            return marketDataProvider;
        } else {
            throw new UnWorkException("还没有登录，请先登录后使用");
        }
    }

    /**
     * @return the managementProvider
     */
    public ManagementProvider getManagementProvider() {
        if (isLoginHistoryData) {
            return managementProvider;
        } else {
            throw new UnWorkException("还没有登录，请先登录后使用");
        }
    }

    /**
     * @return the historyDataProvider
     */
    public HistoryDataProvider getHistoryDataProvider() {
        if (isLoginTrade) {
            return historyDataProvider;
        } else {
            throw new UnWorkException("还没有登录，请先登录后使用");
        }
    }
}
